#include "watchdiinstructionlogic.h"
#include "GeneralDefine.h"
#include "programengine.h"
#include "messagelog.h"
#define D_WAIT_SLEEP_TIME 10000.0

WatchDIInstructionLogic::WatchDIInstructionLogic(QString configFilePathIn, int robotIdIn, ProgramSet *programSetIn,
                                                 RobotIo *ioControllerIn, ProgramEngine *programEngineIn)
{
    programSet=programSetIn;
    robotId=robotIdIn;
    ioController=ioControllerIn;
    programEngine=programEngineIn;
    configFilePath=configFilePathIn;
}

E_PROGRAM_LOOP_RESULT WatchDIInstructionLogic::startWatchDI(int programNum, WatchDIInstruction watchDIInstruct)
{
    qDebug()<<"startWatchDI";
    programEngine->updateProgramSetRegister();

    //等待di条件
    bool waitCondition;
    if(watchDIInstruct.dISwitch=="ON")
    {
        waitCondition=true;
    }
    else
    {
        waitCondition=false;
    }

   do
    {
        if(waitCondition==ioController->getDi(watchDIInstruct.dIIndex-1))
        {
            break;
        }

        if(ENUM_COMMAND_CEASE == programEngine->getEngineStatue() ||
                ENUM_COMMAND_RESET == programEngine->getEngineStatue())
        {
           return E_PROGRAM_LOOP_RESULT_CEASE_STOP;
        }
        realTimeSleep(D_WAIT_SLEEP_TIME);

    }
    while(1);

    //延时
    double tmpDelayTime;
    if(E_WATCHDI_TYPE_TIME==watchDIInstruct.watchDITyde)
    {
        tmpDelayTime=watchDIInstruct.watchTime;
    }
    else
    {
        if(watchDIInstruct.counterIndex<1 || watchDIInstruct.counterIndex>programSet->regRList.size())
        {
            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3017, robotId);
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }
        tmpDelayTime=programSet->regRList[watchDIInstruct.counterIndex-1];
    }

    int sleepCount=0;
    while(1)
    {
        realTimeSleep(D_WAIT_SLEEP_TIME);
        sleepCount++;
        double totalWaitTime=sleepCount*D_WAIT_SLEEP_TIME;
        if(totalWaitTime>tmpDelayTime*1000000)
        {
            break;
        }
        if(ENUM_COMMAND_CEASE == programEngine->getEngineStatue() ||
                ENUM_COMMAND_RESET == programEngine->getEngineStatue())
        {

           return E_PROGRAM_LOOP_RESULT_CEASE_STOP;
        }
    }
    bool tmpValue;
    if(watchDIInstruct.dOSwitch=="ON")
    {
        tmpValue=true;
    }
    else
    {
        tmpValue=false;
    }
    ioController->setDo(watchDIInstruct.dOIndex-1,tmpValue);

    programEngine->calculateNextLineToRun(programNum);
    return programEngine->isTheLastInstruction(programNum);
}


void WatchDIInstructionLogic::realTimeSleep(long long umicoroSecond)
{
    // 处理qt事件
    QCoreApplication::processEvents();

    struct timespec time;
    clock_gettime(CLOCK_REALTIME,&time);
    time.tv_nsec += umicoroSecond * 1000;
    while(time.tv_nsec >= NSEC_PER_SEC)
    {
        time.tv_nsec -= NSEC_PER_SEC;
        ++time.tv_sec;
    }
    clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&time,NULL);

}


void WatchDIInstructionLogic::addMsg(int messageLevel, string componentName, string messageType, int messageCode,
                                     int robotId, int parameter1, int parameter2, int parameter3, int parameter4, QString message)
{
    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;
   // tmpMsg.time = t1.tv_sec;


    QString infomationStr;

    switch(messageCode)
    {

    case 3005:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr("; %1,第%2行， IO号超出已有逻辑ＩＯ范围，请检查指令或ＩＯ配置，").arg(message).arg(parameter3)
                +QString::number(parameter1) + ">="
        +QString::number(parameter2);
        break;


    }
    case 3017:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",寄存器的范围超过限定的最大范围，请修改")+message;
        break;
    }


    default:
    {

    }
    }


    tmpMsg.MessageInformation = infomationStr.toStdString();

    // qDebug()<<"53444444444444444444444"<< tmpMsg.messageCode;
    MessageLog::getInstance()->addMessage(tmpMsg);
}
